//
// Mouse Gesture Recognizer
// (c) Robert Hahn / HTW Dresden
//
// Layer.cs
// --------
// Layer specific classes.
//

using System;
using System.Collections;
using System.ComponentModel;

namespace CNeural
{
	/// <summary>
	/// Specifies the type of a layer in a neural network.
	/// </summary>
	public enum LayerType 
	{
		Input,
		Output,
		Hidden
	}
	
	/// <summary>
	/// Represents a layer of neurons in a neural network.
	/// </summary>
	[Serializable]
	[TypeConverter(typeof(ExpandableObjectConverter))]
	public class NeuronLayer : ArrayList
	{
		#region Fields
		private LayerType type;
		#endregion

		#region Properties
		/// <summary>
		/// Gets or sets the type of the layer.
		/// </summary>
		public LayerType Type 
		{
			get { return this.type; }
			set { this.type = value; }
		}


		/// <summary>
		/// Indexer.
		/// </summary>
		[Browsable(false)]
		public new Neuron this[int index] 
		{
			get { return base[index] as Neuron; }
			set { base[index] = value;	}
		}


		/// <summary>
		/// Gets an array with output values.
		/// </summary>
		public double[] Output 
		{
			get 
			{
				double[] output = new double[this.Count];
				for (int i = 0; i < this.Count; i++) 
				{
					output[i] = this[i].Output;
				}
				return output;
			}
		}
		#endregion

		#region Constructors
		/// <summary>
		/// Constructor.
		/// </summary>
		/// <param name="type">Type of the layer.</param>
		public NeuronLayer(LayerType type) 
		{
			this.type = type;
		}

		public NeuronLayer()
		{
		}
		#endregion

		#region Methods
		/// <summary>
		/// Adds a new neuron to the layer.
		/// </summary>
		/// <param name="n"></param>
		public void Add(Neuron n) 
		{
			base.Add(n);
		}


		/// <summary>
		/// Computes the output for all neurons in the layer.
		/// </summary>
		public void ComputeOutput() 
		{
			foreach (Neuron n in this) 
			{
				n.ComputeOutput();
			}
		}
		#endregion
	}

	
	/// <summary>
	/// Represents a typed array list for neuron layers.
	/// </summary>
	[Serializable]
	[TypeConverter(typeof(ExpandableObjectConverter))]
	public class LayerList : ArrayList 
	{
		#region Methods
		/// <summary>
		/// Adds a new neuron layer to the list.
		/// </summary>
		/// <param name="layer">The layer to add.</param>
		public void Add(NeuronLayer layer) 
		{
			base.Add(layer);
		}
		#endregion
		
		#region Properties
		/// <summary>
		/// Indexer.
		/// </summary>
		public new NeuronLayer this[int index] 
		{
			get 
			{ 
				if (base.Count > index) 
				{
					return base[index] as NeuronLayer; 
				}
				throw new ApplicationException("Layer index out of range.");
			}
			set { base[index] = value; }
		}
		#endregion
	}

}
